﻿using Avalonia;
using Avalonia.ReactiveUI;
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading;
using AutojsController.Config;
using Serilog;
using AutojsController.Helpers;

namespace AutojsController
{
    internal static class NativeMethods
    {
        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool SetForegroundWindow(IntPtr hWnd);

        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool IsIconic(IntPtr hWnd);

        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool FlashWindow(IntPtr hWnd, bool invert);

        public const int SW_RESTORE = 9;
        public const int SW_SHOW = 5;
    }

    internal sealed class Program
    {
        // Initialization code. Don't use any Avalonia, third-party APIs or any
        // SynchronizationContext-reliant code before AppMain is called: things aren't initialized
        // yet and stuff might break.
        [STAThread]
        public static void Main(string[] args)
        {
            const string appName = "AutojsController";
            var _mutex = new Mutex(true, appName, out var createdNew);
            if (!Directory.Exists(Consts.LOG_DIR)) Directory.CreateDirectory(Consts.LOG_DIR);
            var logger = LoggerFactory.GetLogger();

            if (!createdNew)
            {
                BringRunningInstanceToFront();
                return;
            }
            try
            {
                BuildAvaloniaApp()
                    .StartWithClassicDesktopLifetime(args);
            }
            catch(Exception e)
            {
                logger.Error(e, "程序运行错误");
            }
            finally
            {
                _mutex.ReleaseMutex();
            }
        }

        private static void BringRunningInstanceToFront()
        {
            var currentProcess = Process.GetCurrentProcess();
            var currentModule = currentProcess.MainModule;

            var processes = Process.GetProcessesByName(currentProcess.ProcessName)
                .Where(p => p.Id != currentProcess.Id)
                .ToList();

            foreach (var process in processes)
            {
                try
                {
                    if (process.MainModule?.FileName == currentModule?.FileName)
                    {
                        NativeMethods.SetForegroundWindow(process.MainWindowHandle);

                        if (NativeMethods.IsIconic(process.MainWindowHandle))
                        {
                            NativeMethods.ShowWindow(process.MainWindowHandle,
                                NativeMethods.SW_RESTORE);
                        }
                        break;
                    }
                }
                catch
                {
                    //没找到不管
                }
            }
        }


        // Avalonia configuration, don't remove; also used by visual designer.
        public static AppBuilder BuildAvaloniaApp()
            => AppBuilder.Configure<App>()
                .UsePlatformDetect()
                .WithInterFont()
                .LogToTrace()
                .UseReactiveUI();
    }
}
